// main.c 20250316 Renzis
#include <sys/unistd.h>
#include <arch/gdt.h>
#include <arch/tss.h>
#include <arch/cpu.h>
#include <mm/vma.h>
#include <hal/rtc.h>
#include <process.h>

#define LOG_TAG "main"
#include <log.h>

void tests();

void __USER__ user_main() {
    char* log = "Hello, user!\n";
    write(0, log, 14);
    char* argv[] = {
        "First arg",
        0
    };
    char* envp[] = {
        "HOME=/root",
        0
    };
    int pid = fork();
    if (pid == 0) {
        execve("/root/main", argv, envp);
    }
    wait(NULL);
    execve("/root/main", argv, envp);
}

void kswapd(void*);
// Hello Menu
void kernel_main() {
    int stdout = open("/dev/tty", 0);
    char* p = "Hello, kswapd!\n";
    kthread_create(kswapd, p);

    tests();

    show_rtc_time();

    LOGP("Kernel Initalization Complete!\n");

    if (!cur_proc->mm) {
        cur_proc->mm = mm_alloc(cur_proc);
        struct vma* vma = vma_alloc();
        vma->start = cur_proc->mm->ustack_bottom;
        vma->end = PG_ALIGN(cur_proc->mm->ustack_top + 0xFFF);
        vma->flags = VMA_READ | VMA_WRITE | VMA_NO_SWAP;
        vma_list_append(cur_proc->mm, vma);
    }

    cli();
    assign_return_context(0, cur_proc, KSTK_AREA_END);

    cur_proc->context.ctx->ctx.eip = (u32)user_main;
    cur_proc->context.ctx->ctx.esp0 = cur_proc->mm->ustack_top;
    cur_proc->context.ctx->ctx.ss0 = SS_R3_DATA;
    cur_proc->context.ctx->ctx.eflags.flags.IF = 1;

    asm volatile("pushl %0\n"
        "jmp switch_to\n" ::"r"(cur_proc)
        : "memory");
}

// print tip
// void printS()
// {
//     char *p = "kernel_v0.6>";
//     puts(p);
// }

// print help
// void showhelp()
// {
//     char *help = "this is help\n";
//     puts(help);
// }

// void readbuf(char *buf, int len)
// {
//     int i = 0;
//     char c;
//     while (1) {
//         c = getchar();
//         if (c == '\n') {
//             break;
//         } else if ((c > '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
//             if (i >= len - 1) continue;
//             buf[i++] = c;
//             putc(c, WHITEBLACKWORD);
//         } else if (c == '\b') {
//             if (i == 0) continue;
//             buf[i--] = 0;
//             putc('\b', WHITEBLACKWORD);
//         }
//     }
//     buf[i] = 0;
// }

// like shell
// void _shell()
// {
//     char *command[] = { ": command not found!\n", "clear", "poweroff" };
//     enum { err, clr, poweroff };
//     int BUF_LEN = 32;
//     // clear();
//     showhelp();
//     char cmdbuf[BUF_LEN + 1];
//     while (1) {
//         printS();
//         readbuf(cmdbuf, BUF_LEN);
//         //  ...
//         if (strequ(cmdbuf, command[poweroff])) {
//             //_poweroff();
//         } else if (strequ(cmdbuf, command[clr])) {
//             clear();
//         } else {
//             puts(cmdbuf);
//             puts(command[err]);
//         }
//     }
// }
